package org.wattdepot.cli;

import java.util.List;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClientException;
import org.wattdepot.resource.source.jaxb.Source;
import org.wattdepot.util.tstamp.Tstamp;
import javax.xml.datatype.XMLGregorianCalendar;

/**
 * A class that prints out the power generated or consumed for the day for a certain interval
 * under a criteria of max, min, or average.
 * @author wing cheung ma, edwin lim
 */
public class PowerGeneratedDay extends CommandLineInterface implements WattDepotCliCommand {

  /**
   * Constructor for the PowerGeneratedDay class.
   * @param args list of input arguments
   * @return a string with the power generated or consumed
   */
  @Override
  public String doCommand(List<String> args) {
    
    String type = args.get(0);
    String source = args.get(1);
    String day = args.get(2);
    String interval = args.get(3);
    String statistic = args.get(4);
    
    String noSuccess = "Unsuccessful";
    String result = "";
    String average = "average";
    double powerGen = 0.0;
    String consumedOption = "consumed";
    String generatedOption = "generated";
    String max = "max";
    String min = "min";
    Integer intervalInt = 1;
    
    try {
      intervalInt = Integer.parseInt(interval);
    }
    catch (NumberFormatException e) {
      return "Problem with the interval inputted";
    }
    
    Integer intervalMinutes = intervalInt;
    intervalInt = 1440 / intervalInt;
    double[] timeStampList = new double[intervalInt];
    
    Source serr = null;
    try {
      serr = searchSource(source);
    }
    catch (WattDepotClientException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
    
    if (serr == null) {
      return sourceNotFound;
    }
    
    //retrieve time stamp to get all power generated based in a interval
    XMLGregorianCalendar now = null;
    try {
      now = Tstamp.makeTimestamp(day);
    }
    catch (Exception e) {
      System.out.println("should never happen.");
    }
    
    if (type.equalsIgnoreCase(generatedOption)) {
      for (int i = 0; i < intervalInt; i++) {
        now = Tstamp.incrementMinutes(now, intervalMinutes);
        try {
          powerGen = client.getPowerGenerated(source, now);
        }
        catch (NotAuthorizedException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (ResourceNotFoundException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (BadXmlException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (MiscClientException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        timeStampList[i] = powerGen;
      }
    }
    
    else if (type.equalsIgnoreCase(consumedOption)) {
      for (int i = 0; i < intervalInt; i++) {
        now = Tstamp.incrementMinutes(now, intervalMinutes);
        try {
          powerGen = client.getPowerConsumed(source, now);
        }
        catch (NotAuthorizedException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (ResourceNotFoundException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (BadXmlException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        catch (MiscClientException e) {
        // TODO Auto-generated catch block
          e.printStackTrace();
        }
        timeStampList[i] = powerGen;
      }
      
    }
    
    //max of the day
    if (statistic.contains(max)) {
      double maxPower = timeStampList[0]; 
      for (int i = 1; i < intervalInt - 1; i++) {
        
        if (timeStampList[i] > maxPower) {
          maxPower = timeStampList[i];
        }
        
      }
      result = Double.toString(maxPower);
      return result;
    }
    
    //min of the day
    else if (statistic.contains(min)) {
      double minPower = timeStampList[0]; 
      for (int i = 1; i < intervalInt - 1; i++) {
        if (timeStampList[i] < minPower) {
          minPower = timeStampList[i];
        }
        
      }
      result = Double.toString(minPower);
      return result;
    }
    
    //average of the day
    else if (statistic.contains(average)) {
      double averagePower = timeStampList[0];
      
      for (int i = 1; i < intervalInt - 1; i++) {
        averagePower = averagePower + timeStampList[i]; 
      }
      
      double avg = averagePower / intervalInt;
      result = Double.toString(avg);
      return result;
      
    }
    
    return noSuccess;
  }
  
}
